#ifndef XMPPCONNECTION_H
#define XMPPCONNECTION_H

#include <gloox/connectionlistener.h>
#include <gloox/presencehandler.h>
#include <gloox/messagehandler.h>
#include <gloox/messagesessionhandler.h>
#include <QObject>
#include <QString>

#include "../handlers.h"

namespace gloox
{
struct Client;
struct RosterManager;
struct MessageSession;
struct Stanza;
}

namespace Kajim
{
namespace XMPP {

struct SessionThread;

/**
 * \class Kajim::XMPP::Connection
 *
 * Class Kajim::XMPP::Connection represents client connection to the jabber
 * server.
 */
class Connection : public ::QObject, ::gloox::ConnectionListener, ::gloox::PresenceHandler,
    ::gloox::MessageSessionHandler, ::gloox::MessageHandler
{
    Q_OBJECT
public:
    Connection(int accountHandler);
    ~Connection();

    ::gloox::Presence presence();

    // handlers from gloox::ConnectionListener
    virtual void onConnect();
    virtual void onDisconnect(gloox::ConnectionError e);
    virtual bool onTLSConnect(const gloox::CertInfo& info);

    // from gloox::PresenceHandler
    virtual void handlePresence(gloox::Stanza * stanza);

    // from gloox::MessageSessionHandler
    virtual void handleMessageSession(::gloox::MessageSession *session);

    // from gloox::MessageHandler
    virtual void handleMessage(::gloox::Stanza *stanza, ::gloox::MessageSession *session = 0);

    bool isConnected();

    /**
     * \brief Get name of contact using its JID
     *
     * \param a
     */
    QString contactName(const QString & jid);

    /**
     * @return pointer to gloox::RosterManager object or 0 if roster manager is not available.
     */
    ::gloox::RosterManager * rosterManager();

    gloox::MessageSession * messageSession(const QString & jid);

public slots:
    void login(::gloox::Presence presence);
    void logout();
    void sendMessage(const QString & peerJid, const QString & body, const QString & subject);

signals:
    void connected(int accountHandler);
    void disconnected(int accountHandler);
    void connectionError(gloox::ConnectionError);
    void messageReceived(int accountHandler, const QString & peerJid, const QString & body, const QString & subject);

private:
    struct Private;
    Private * d;
};

}
}
#endif
